package edu.hcmus.sow.web.document;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import edu.hcmus.sow.domain.FileAccessRight;
import edu.hcmus.sow.domain.FileRevision;
import edu.hcmus.sow.domain.Folder;
import edu.hcmus.sow.service.DocumentService;
import edu.hcmus.sow.service.SecurityService;
import edu.hcmus.sow.utils.SecurityUtil;

@Controller
public class DocumentController {

   // ~ Instance fields
   // ================================================================================================
   @Autowired
   private DocumentService documentService;

   @Autowired
   private SecurityService securityService;

   // ~ Repository's methods
   // ================================================================================================
   @PreAuthorize("hasPermission(#id, 'edu.hcmus.sow.domain.Folder', read) or hasPermission(#id, 'edu.hcmus.sow.domain.Folder', write) or hasPermission(#id, 'edu.hcmus.sow.domain.Folder', admin) or hasRole('ROLE_ADMINISTRATOR')")
   @RequestMapping("/repository/{id}")
   public ModelAndView viewRepository(@PathVariable("id") Integer id) {
      ModelAndView mav = new ModelAndView();

      Folder currentFolder = documentService.getFolderByID(id);
      List<Folder> rootFolders = getRootFolders(currentFolder);

      // get folders list which in parent folder
      List<Folder> folders = documentService.getFoldersByParentID(id);
      mav.addObject("folders", folders);

      // get files list which in the folder
      List<FileRevision> files = documentService.getLatestFilesVersionByFolderID(id);
      // filter
      files = filterFiles(files);
      mav.addObject("files", files);

      // set parent folder
      mav.addObject("currentFolderID", id);
      mav.addObject("folderForm", new FolderForm(id));

      mav.addObject("currentFolder", currentFolder);
      mav.addObject("rootFolders", rootFolders);
      mav.addObject(
            "isWrite",
            securityService.hasPermission(currentFolder, BasePermission.WRITE)
                  || securityService.hasRole("ROLE_ADMINISTRATOR"));

      mav.setViewName("repository");

      return mav;
   }

   private List<Folder> getRootFolders(Folder folder) {
      List<Folder> folders = new ArrayList<Folder>();
      while (folder.getParentID() != null) {
         folder = documentService.getFolderByID(folder.getParentID());
         folders.add(0, folder);
      }

      return folders;
   }

   private List<FileRevision> filterFiles(List<FileRevision> files) {
      Integer userID = SecurityUtil.getCurrentLoggedinUserID();
      List<FileRevision> fileRevisions = new ArrayList<FileRevision>();
      for (FileRevision fr : files) {
         FileAccessRight far = documentService.findByFileAndUser(fr.getFileID(), userID);
         String accessRight = far == null ? fr.getFile().getDefaultAccessRight() : far.getAccessRight();
         if (!"H".equals(accessRight) || securityService.hasRole("ROLE_ADMINISTRATOR")) {
            fileRevisions.add(fr);
         }
      }

      return fileRevisions;
   }
}
